package common.utils;

import cn.hutool.core.date.DateTime;
import lombok.var;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;

public class TimeUtil {

    public static boolean equals(Date time1, Date time2) {
        return time1.getTime() == time2.getTime();
    }

    public static boolean eq(Date time1, Date time2) {
        return equals(time1, time2);
    }

    public static SimpleDateFormat getFormat(String format) {
        return new SimpleDateFormat(format);
    }

    public static SimpleDateFormat format_ym = getFormat("yyyy-MM");
    public static SimpleDateFormat format_ymd = getFormat("yyyy-MM-dd");
    public static SimpleDateFormat format_ymdhms = getFormat("yyyy-MM-dd HH:mm:ss");
    public static SimpleDateFormat format_ymdhmss = getFormat("yyyy-MM-dd HH:mm:ss.SSS");
    public static SimpleDateFormat format_ymdhmsss = getFormat("yyyy-MM-dd HH:mm:ss.SSSSSS");
    public static SimpleDateFormat format_underline_ymdhms = getFormat("yyyy_MM_dd_HH_mm_ss");
    public static SimpleDateFormat format_joined_ymdhms = getFormat("yyyyMMddHHmmss");
    public static SimpleDateFormat format_y = getFormat("yyyy");
    public static SimpleDateFormat format_d = getFormat("dd");
    public static SimpleDateFormat format_hanzi_ymd = getFormat("yyyy年MM月dd日");

    public static Date fromString(String timeString) {
        try {
            switch (timeString.length()) {
                case 4:
                    return format_y.parse(timeString);
                case 7:
                    return format_ym.parse(timeString);
                case 10:
                    return format_ymd.parse(timeString);
                case 19:
                    return format_ymdhms.parse(timeString);
                case 23:
                    return format_ymdhmss.parse(timeString);
                case 26:
                    return format_ymdhmsss.parse(timeString);
            }
            return Timestamp.valueOf(timeString);
        } catch (Exception ex) {
            return null;
        }
    }

    public static Timestamp parse(Object time) {
        return toSqlTimestamp(fromString(time.toString()));
    }

    public static Timestamp getDateTime(Object time) {
        return parse(time);
    }

    public static Timestamp toSqlTimestamp(Date time) {
        return new Timestamp(time.getTime());
    }

    public static Timestamp getSqlTimestamp(Date time) {
        return toSqlTimestamp(time);
    }

    public static Timestamp parseSqlTimestamp(Object time) throws Exception {
        return getSqlTimestamp(parse(time));
    }

    public static DateTime toHtDateTime(Date time) {
        return DateTime.of(time);
    }

    public static String toString(Date time, SimpleDateFormat format) {
        return format.format(time);
    }

    public static String getString(Date time, SimpleDateFormat format) {
        return toString(time, format);
    }

    public static String toString(Date time, String format) {
        return getString(time, getFormat(format));
    }

    public static String getString(Date time, String format) {
        return toString(time, format);
    }

    /**
     * 取日期,小时置0
     */
    public static Timestamp getDate(Date time) {
        return parse(toString(time, "yyyy-MM-dd 00:00:00"));
    }

    public static String getTimePart(Date time) {
        return toString(time, "hh:mm");
    }

    //lambda的between(column, start, end)方法包含start和end，所以end有时要before一下
    public static Date before(Date time) {
        //double->long
        return new Date(time.getTime() - 1);
    }

    public static Date addSeconds(Date time, double seconds) {
        //double->long
        return new Date(time.getTime() + (long) (seconds * 1000));
    }

    public static Timestamp addDays(Date time, double days) {
        //double->long
        return new Timestamp(time.getTime() + (long) (days * 24 * 60 * 60 * 1000));
    }

    public static Date getNow() {
        return new Date();
    }

    /**
     * 毫秒
     */
    public static long getNowTicks() {
        return getNow().getTime();
    }

    /**
     * 毫秒
     */
    public static final long OneDayTicks = 24L * 60 * 60 * 1000;

    public static Date getToday() {
        var ticks = getNowTicks();
        ticks = ticks - ticks % OneDayTicks;
        return new Date(ticks);
    }

    public static Date getTomorrow() {
        return new Date(getToday().getTime() + OneDayTicks);
    }

    public static String getNowString() {
        return format_ymdhms.format(getNow());
    }

    public static String getNowDateString() {
        return format_ymd.format(getNow());
    }

    public static String getNowStringWithMilliseconds() {
        return format_ymdhmss.format(getNow());
    }

    public static String getNowString(SimpleDateFormat format) {
        return format.format(getNow());
    }

    public static String getNowString(String format) {
        return getNowString(getFormat(format));
    }

    /**
     * yyyy_MM_dd_HH_mm_ss
     */
    public static String getNowUnderlineString() {
        return format_underline_ymdhms.format(getNow());
    }

    public static String getNowJoinedString() {
        return format_joined_ymdhms.format(getNow());
    }

    /**
     * yyyy年MM月dd日
     */
    public static String getNowDateHanziString() {
        return format_hanzi_ymd.format(getNow());
    }


    public static String getDateString(Date date) {
        return format_ymd.format(date);
    }

    public static String getHanziDateString(Date time) {
        if (time == null)
            return null;
        return format_hanzi_ymd.format(time);
    }

    public static String getDayString(Date date) {
        return format_d.format(date);
    }

    public static Date getYear(int year) throws Exception {
        return fromString(year + "-01-01 00:00:00");
    }

    public static int getYearInt(Date time) {
        return toHtDateTime(time).year();
    }

    public static String getYearString(Date date) {
        return getYearInt(date) + "";
    }

    public static String getNowYearString() {
        return getYearString(getNow());
    }

    public static int getNowYearInt() {
        return ConvertUtil.toInt(getNowYearString());
    }

    public static Date getNowYear() throws Exception {
        return fromString(getNowYearString() + "-01-01 00:00:00");
    }

    public static Date getNextYear() throws Exception {
        return fromString((getNowYearInt() + 1) + "-01-01 00:00:00");
    }

    public static Date getNextYear(int year) throws Exception {
        return fromString((year + 1) + "-01-01 00:00:00");
    }

    public static boolean between(Date time, Date start, Date end) {
        var timeValue = time.getTime();
        var startValue = start.getTime();
        var endValue = end.getTime();
        return timeValue >= startValue && timeValue <= endValue;
    }

    public static long getTotalMilliseconds(Date time) {
        return time.getTime();
    }

    public static int offsetDays(Date from, Date to) {
        //内置的方法compareTo==after这里不适用
        var offset = from.getTime() - to.getTime();//毫秒
        return (int) (offset / 1000 / 60 / 60 / 24);
    }

    public static int offsetNowSeconds(Date time) {
        //内置的方法compareTo==after这里不适用
        var offset = getNow().getTime() - time.getTime();//毫秒
        return (int) (offset / 1000);
    }


    //---------------- java.sql.Timestamp; -------------------start
    public static Timestamp newSqlTimestamp(int year, int month, int day) {
        return Timestamp.valueOf(StringUtil.format("{}-{}-{} 00:00:00", year, month, day));
    }

    public static Timestamp newSqlTimestamp(int year, int month, int day, int hour, int minute, int second) {
        return Timestamp.valueOf(StringUtil.format("{}-{}-{} {}:{}:{}",
                year, month, day, hour, minute, second));
    }

    public static Timestamp getSqlTimestamp(String timeString) throws Exception {
        return getSqlTimestamp(fromString(timeString));
    }

    /**
     * 精确到秒，毫秒为0
     */
    public static Timestamp getNowSqlTimestamp() {
        return new Timestamp(getNow().getTime() / 1000 * 1000);
    }

    //---------------- java.sql.Timestamp; -------------------end


    public static Date newDate(int year, int month, int day) {
        return newSqlTimestamp(year, month, day);
    }

    public static Date newTime(int year, int month, int day, int hour, int minute, int second) {
        return newSqlTimestamp(year, month, day, hour, minute, second);
    }


    public static long getNowLongStamp() {
        return System.currentTimeMillis();
    }

    public static int getNowStamp() {
        return (int) (System.currentTimeMillis() / 1000);
    }

    public static long stampStart = newTime(1970, 1, 1, 8, 0, 0).getTime();

    public static Date fromStamp(int timestamp) {
        return new Date(stampStart + timestamp * 1000L);//秒
    }

    public static Date fromStamp(long timestamp) {
        return new Date(stampStart + timestamp);//毫秒
    }

}
